package com.guiji.text2video.fastvideo.utils;

import com.guiji.text2video.fastvideo.domain.vo.Text2videoPoolsStat;
import com.guiji.text2video.fastvideo.service.Impl.Text2videoPoolsStatServiceImpl;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.core.task.TaskRejectedException;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.util.concurrent.ListenableFuture;

import java.util.Date;
import java.util.concurrent.*;

/**
 * @program: VisiableThreadPoolTaskExecutor
 * @description:监控线程池运行状态
 * @author: scl
 * @create: 2021-05-11 13:53
 */
public class VisiableThreadPoolTaskExecutor extends ThreadPoolTaskExecutor {

    private static final Logger logger = LoggerFactory.getLogger(VisiableThreadPoolTaskExecutor.class);

    //当每个线程访问这个 balance 变量时，ThreadLocal会为每个线程提供一份变量，各个线程互不影响。
    private ThreadLocal<Integer> local = ThreadLocal.withInitial(() -> 0);

    Text2videoPoolsStatServiceImpl poolsStat;

    static String serverIP=GetLocalIpUtil.getIp();

    public VisiableThreadPoolTaskExecutor(Text2videoPoolsStatServiceImpl poolsStat) {
        this.poolsStat = poolsStat;

    }

    private void showThreadPoolInfo(String prefix) {
        ThreadPoolExecutor threadPoolExecutor = getThreadPoolExecutor();
        if (null == threadPoolExecutor) {
            return;
        }
        //保证不是任务提交触发的，定时任务触发的
        if (threadPoolExecutor.getActiveCount() != 0 && prefix.equals("execute()")) {
            Text2videoPoolsStat vo = new Text2videoPoolsStat();
            vo.setActiveCount(threadPoolExecutor.getActiveCount() + "");
            vo.setQueueSize(threadPoolExecutor.getQueue().size() + "");
            vo.setTaskCount(threadPoolExecutor.getTaskCount() + "");
            vo.setCompletedTaskCount(threadPoolExecutor.getCompletedTaskCount() + "");
            vo.setPoolsName(this.getThreadNamePrefix());
            vo.setCreateTime(new Date());
            vo.setBackup1(serverIP);
            poolsStat.insertText2videoPoolsStat(vo);
        }

/*        logger.info("{}, {},taskCount [{}], completedTaskCount [{}], activeCount [{}], queueSize [{}]",
                this.getThreadNamePrefix(),
                prefix,
                threadPoolExecutor.getTaskCount(),
                threadPoolExecutor.getCompletedTaskCount(),
                threadPoolExecutor.getActiveCount(),
                threadPoolExecutor.getQueue().size());*/
    }

    /**
     * @descp: 直接提交的、有界的、无界的、优先任务队列。覆盖父类方法。无界的任务队列（LinkedBlockingQueue）
     * @param: BlockingQueue<Runnable> 任务队列（BlockingQueue）指存放被提交但尚未被执行的任务的队列。
     * @Author: scl
     * @Date: 2021/7/16 13:41
     */
    @Override
    protected BlockingQueue<Runnable> createQueue(int queueCapacity) {
        return (BlockingQueue)(queueCapacity > 0 ? new LinkedBlockingQueue(queueCapacity) : new SynchronousQueue());
        //return (BlockingQueue)(queueCapacity > 0 ? new PriorityBlockingQueue(queueCapacity) : new SynchronousQueue());

    }

    @Override
    public void execute(Runnable command) {

        //保证是定时任务触发
        if (null == command) {
            showThreadPoolInfo("execute()");
            return;
        }//对于每个任务，execute会被循环执行
        ThreadPoolExecutor executor = this.getThreadPoolExecutor();
        //int priority = local.get();
        try {
            //executor.execute(new PriorityRunnable(command,priority));
            executor.execute(command);
        } catch (RejectedExecutionException var4) {
            throw new TaskRejectedException("Executor [" + executor + "] did not accept task: " + command, var4);
        }finally {
            //local.set(0);
        }
    }

    public void executePriority(PriorityRunnable command) {
        if (null == command) {
            showThreadPoolInfo("execute()");
            return;
        }
        super.execute(command);
    }



}
